﻿using mozhi.smarterp.BasicData.Currencies.Repositories;
using Mozhi.Abp.OperationLog;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Guids;

namespace mozhi.smarterp.BasicData.Currencies
{
    public class CurrencyAppService : BasicDataAppService , ICurrencyAppService
    {
        private ICurrencyRepository _repository;
        private IGuidGenerator _guidGenerator;

        public CurrencyAppService(ICurrencyRepository currencyRepository , IGuidGenerator guidGenerator) 
        {
            _repository = currencyRepository;
            _guidGenerator = guidGenerator;
        }

        public async Task<CurrencyDto> CreateAsync(CurrencyCreateDto input)
        {
            await ValidateDuplicateAsync(null, input.Code, input.Name);

            var entity = new Currency(_guidGenerator.Create(), input.Code, input.Name, input.Symbol, input.Activated);

            await _repository.InsertAsync(entity);

            //await _operationLogger.LogAsync(nameof(Currency), OperationType.Create, entity, null);

            return ObjectMapper.Map<Currency, CurrencyDto>(entity);
        }

        public async Task<CurrencyDto> GetAsync(Guid id)
        {
            var currency = await _repository.GetAsync(id);

            return ObjectMapper.Map<Currency , CurrencyDto>(currency);
        }

        public async Task<PagedResultDto<CurrencyDto>> GetListAsync(PagedResultRequestDto filter)
        {
            var count = await _repository.GetCountAsync();

            var currencies = await _repository.GetPagedListAsync(filter.SkipCount, filter.MaxResultCount, "Code");

            var result = new PagedResultDto<CurrencyDto>();

            result.TotalCount = count;
            result.Items = ObjectMapper.Map<List<Currency>, List<CurrencyDto>>(currencies);

            return result;
        }

        public async Task<CurrencyDto> UpdateAsync(CurrencyUpdateDto input)
        {
            var currency = await _repository.GetAsync(input.Id);

            if (currency == null)
                throw new BusinessException("100000", $"币别：{input.Id}不存在");

            var source = ObjectMapper.Map<Currency, CurrencyDto>(currency);

            await ValidateDuplicateAsync(input.Id, input.Code, input.Name);

            currency.Change(input.Code, input.Name, input.Activated);

            await _repository.UpdateAsync(currency);

            var target = ObjectMapper.Map<Currency, CurrencyDto>(currency);

            //await _operationLogger.LogAsync(nameof(Currency), OperationType.Update, source, target);

            return target;
        }

        public async Task DeleteAsync(Guid id)
        {
            var match = await _repository.GetAsync(id);

            if (match == null)
                throw new BusinessException("100000", $"币别：{id}不存在");

            await _repository.DeleteAsync(match);

            //await _operationLogger.LogAsync(nameof(Currency), OperationType.Delete, match , null);
        }

        #region
        private async Task ValidateDuplicateAsync(Guid? id , string code , string name)
        {
            var excludeIds = id.HasValue ? new List<Guid>() { id.Value } : null;

            var matchCount = await _repository.CountAsync(code, null , excludeIds);

            if (matchCount > 0)
                throw new UserFriendlyException($"币别：{code}已存在", "100000");

            matchCount = await _repository.CountAsync(null, name, excludeIds);

            if (matchCount > 0)
                throw new UserFriendlyException($"币别：{name}已存在", "100000");
        }
        #endregion
    }
}
